#!/usr/bin/env python

import numpy as np
import matplotlib.pyplot as plt
import sys
import json

def load_results(path):
    with open(path) as f:
        for line in f:
            yield json.loads(line.strip())


def main(args):
    path = args[0] if len(args) > 0 else 'output.json'
    output = args[1] if len(args) > 1 else None

    graphs = dict()

    xticks = set()

    for doc in load_results(path):
        context = doc['context']
        values = graphs.get(context, [])
        times = [round(t / 1000000000.0, 3) for t in doc['times']]
        values.append((doc['concurrency'], times, doc))
        graphs[context] = values
        xticks.add(doc['concurrency'])

    _, axes = plt.subplots(nrows=len(graphs), sharex=True)

    try:
        axes = iter(axes)
    except TypeError:
        axes = [axes]

    plt.xlabel('concurrency')

    for axis, (context, items) in zip(axes, graphs.items()):
        axis.set_title(context)
        axis.set_ylabel('matches')

        axis2 = axis.twinx()
        axis2.set_ylabel('seconds')

        arrays = []
        ticks = []

        for i, (concurrency, times, doc) in enumerate(items):
            matches = doc['matches']
            mismatches = doc['mismatches']
            errors = doc['count'] - doc['matches'] - doc['mismatches']

            axis.bar([(i + 1) - 0.3], matches, width=.6, color='g', alpha=.2)
            axis.bar([(i + 1) - 0.3], mismatches, width=.6, bottom=matches, color='y', alpha=.2)
            axis.bar([(i + 1) - 0.3], errors, width=.6, bottom=matches + mismatches, color='r', alpha=.2)

            ticks.append(str(concurrency))
            arrays.append(times)

        bp = axis2.boxplot(arrays, labels=ticks, showmeans=True, widths=.4)
        colorize_bp(axis2, bp, len(arrays))

    if output is None:
        plt.show()
    else:
        plt.savefig(output, format='png', dpi=(72 * 4))

    #print graphs
    return 0


from matplotlib.patches import Polygon


def colorize_bp(axis, bp, count, color='white'):
    for i in range(count):
        box = bp['boxes'][i]
        boxX = []
        boxY = []

        for j in range(5):
            boxX.append(box.get_xdata()[j])
            boxY.append(box.get_ydata()[j])

        boxCoords = zip(boxX,boxY)
        # Alternate between Dark Khaki and Royal Blue
        boxPolygon = Polygon(boxCoords, facecolor=color)
        axis.add_patch(boxPolygon)


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]) or 0)
